Terraform 1.8で追加されたencode_expr関数を使って、tfe providerでHCP TerraformのVariableを定義してみる
Terraform 1.8でencode_expr
関数が追加されました。
この関数は、TerraformでHCP TerraformのVariablesを書く際に便利です。
Release v1.8.0 · hashicorp/terraform
encode_expr関数とは
HCL形式の値をStringに変換する関数です。
使用用途は限定的で、ドキュメントに以下の記述があるほどです。
provider::terraform::encode_expr is a rarely-needed function
encode_exprから引用
主な使用用途は、HCP TerraformのVariables定義です。(他のユースケースでは使用をお勧めしない旨もドキュメントにありました)
HCP Terraformでは、Workspaceに対してVariablesを渡す機能があります。
tfe_variable
のvalue
はStringである必要があるため、Terraform varialbeでString以外を渡す際に一工夫(後述)必要だったのですが、encode_expr
を使えば以下のように書けます。
terraform { required_providers { terraform = { source = "terraform.io/builtin/terraform" } } } locals { workspace_vars = { example1 = "Hello" example2 = ["A", "B"] example3 = { key1 = "value1", key2 = "value2" } } } resource "tfe_variable" "test" { for_each = local.workspace_vars category = "terraform" workspace_id = tfe_workspace.test.id key = each.key value = provider::terraform::encode_expr(each.value) hcl = true }
やってみた
Terraform CloudのVariables設定を、従来の方法とexprencode関数を使う方法でやってみました。
Variablesには以下の値を設定します。
従来の方法(encode_exprを使わない)
以下は、HCP TerraformのVariable(Terraform変数)を、for_eachを使って定義する例です。
provider "tfe" { hostname = "app.terraform.io" } resource "tfe_workspace" "test" { name = "variables-test" organization = "<HCP Terraform Organization名>" } locals { workspace_vars = { example1 = "Hello" example2 = ["A", "B"] example3 = { key1 = "value1", key2 = "value2" } } } resource "tfe_variable" "test" { for_each = local.workspace_vars category = "terraform" workspace_id = tfe_workspace.test.id key = each.key value = jsonencode(each.value) hcl = true }
注目してほしいのは、ハイライト箇所のjsonencode
関数です。
tfe_variable
のvalue
はstring
で有る必要があります。
そのため、list
やmap
を渡す場合は、jsonencode等を使ってStringに変換する必要があります。
- tfe_variable: list(string) not supported · Issue #188 · hashicorp/terraform-provider-tfe
- tfe_variable doesn't support complex objects · Issue #433 · hashicorp/terraform-provider-tfe
本来なら、HCLにエンコードしたいのですが、1.8以前には関数はありませんでした。
また、上記コードは問題ありませんでしたが、この方法は複雑なObject型を扱う際に問題があったようです。
v1.8以降(exprencodeを使う)
HCLにエンコードする関数encode_expr
がサポートされたので、以下のように置き換えられます。
用途に適した関数を利用することで、読む側に意図が伝わりやすくなったかと思います。
provider "tfe" { hostname = "app.terraform.io" } resource "tfe_workspace" "test" { name = "variables-test" organization = "classmethod-sandbox" } +terraform { + required_providers { + terraform = { + source = "terraform.io/builtin/terraform" + } + } +} locals { workspace_vars = { example1 = "Hello" example2 = ["A", "B"] example3 = { key1 = "value1", key2 = "value2" } } } resource "tfe_variable" "test" { for_each = local.workspace_vars category = "terraform" workspace_id = tfe_workspace.test.id key = each.key - value = jsonencode(each.value) + value = provider::terraform::encode_expr(each.value) hcl = true }
encode_expr
は組み込み関数ではなく、Provider関数です。
ほとんどのTerraformモジュールでは使われないため、Provider関数にしたようです。
terraform.io/builtin/terraform provider, rather than being language builtins, due to their Terraform-domain-specific nature and the fact that they should not be needed by most Terraform module authors.
[アップデート]TerraformのProviderが関数を定義できるようになりました | DevelopersIO
おわりに
Terraform 1.8で追加されたencode_expr
関数についてでした。
使用用途は限定的ですが、Issueを見る限り困っていた人は多くいたみたいです。
tfe providerを使ってHCP TerraformのVariableを定義する際に、encode_expr
関数をぜひ使ってみてください。
以上、AWS事業本部の佐藤(@chari7311)でした。